<template>
  <div class="data-panel" :style="`${props.border ? '' : 'border: none'};padding: ${props.padding}`">
    <bc-query
      ref="bcQueryRef"
      v-if="props.miniQuery === false && queryItems?.length > 0"
      :queries="queryItems"
      :params="props.queryParams"
      @query="handleQuery"
      @reset="handleReset"
    />
    <div class="toolbar-panel">
      <slot name="toolbar">
        <div class="not-toolbar"></div>
      </slot>
      <div v-if="props.miniQuery" class="toolbar-query">
        <bc-mini-query :queries="queryItems" @query="handleQuery" />
      </div>
    </div>
    <bc-table
      v-bind="props.tableAttrs"
      ref="bcTabelRef"
      :columns="columns"
      :dataSource="props.dataSource"
      :query="queryForm"
      :otherQuery="props.otherQuery"
      :paginationLayout="props.paginationLayout"
      @selection-change="handleSelectionChange"
      @radio-change="handleRadioChange"
      @cell-click="handleCellClick"
    >
      <template #[item.slotName]="{ scope }" v-for="(item, index) in columns.filter((i) => i.slotName)" :key="index">
        <slot :name="item.slotName" :scope="scope"></slot>
      </template>
    </bc-table>
  </div>
</template>

<script setup>
import BcQuery from '@/components/bcQuery/BcQuery.vue'
import BcMiniQuery from '@/components/bcQuery/Mini.vue'
import BcTable from '@/components/bcTable/BcTable.vue'
import { nextTick } from 'vue'

const props = defineProps({
  /**
   * type: select|date|month|number|datetime|range
   * prop: table key
   * queryProp: form key（不选默认使用prop）
   * startProp: date|month|datetime|range专用，起始值key
   * endProp: date|month|datetime|range专用，结束值key
   * label: 字段名
   * options: select专用，枚举项[{value:"",label:""}]
   * attrs: 各输入框原始属性
   * slotName: 表格自定义列插槽名称
   * width: 列宽度
   * fixed: 固定左右侧
   * format: date|month|datetime专用，时间展示格式
   */
  columns: {
    type: Array,
    default: () => [],
  },
  // 通过接口|list获取数据
  dataSource: {
    type: [Function, Array],
    default: () => [],
  },
  // 是否展示边框
  border: {
    type: Boolean,
    default: true,
  },
  // 间距
  padding: {
    type: [Number, String],
    default: '16px',
  },
  // el-table默认属性
  tableAttrs: {
    type: Object,
    default: () => {},
  },
  // 其他参数
  otherQuery: {
    type: Object,
    default: () => {},
  },
  miniQuery: {
    type: Boolean,
    default: false,
  },
  queryParams: {
    type: Object,
    default: () => {},
  },
  paginationLayout: {
    type: String,
    default: 'total, sizes, prev, pager, next, jumper',
  },
})

const emits = defineEmits(['selection-change', 'radio-change', 'cell-click'])

// 表格回调函数
const handleSelectionChange = (value) => {
  emits('selection-change', value)
}
const handleRadioChange = (value) => {
  emits('radio-change', value)
}
const handleCellClick = (value) => {
  emits('cell-click', value)
}
// 数据源
const bcTabelRef = ref(null)
const load = () => {
  nextTick(() => {
    bcTabelRef.value.load()
  })
}
const getSelection = () => {
  return bcTabelRef.value.getSelection()
}

// 筛选项
const bcQueryRef = ref(null)
const queryForm = ref({})
// 过滤出筛选项列表
const queryItems = computed(() => {
  return props.columns
    .filter((i) => i.search)
    .map((item) => {
      const { queryType, type, queryProp, prop } = item
      return {
        ...item,
        prop: queryProp || prop,
        type: queryType || type,
      }
    })
})
// 筛选项查询
const handleQuery = (info) => {
  queryForm.value = { ...info }
}
// 筛选项重置
const handleReset = () => {
  queryForm.value = {}
}
const getQueryForm = async () => {
  await nextTick(() => {})
  return bcQueryRef.value.getQueryForm()
}

defineExpose({
  load,
  getSelection,
  getQueryForm,
})
</script>

<style lang="scss" scoped>
.data-panel {
  width: 100%;
  height: 100%;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  background-color: #fff;
  .toolbar-panel:not(:has(.not-toolbar)) {
    padding: 0 0 12px;
  }
  .toolbar-panel:has(.toolbar-query) {
    padding-bottom: 12px;
    justify-content: space-between;
  }
  .toolbar-query {
    flex: 1;
    max-width: 60%;
  }
  .toolbar-panel {
    display: flex;
  }
}
</style>
